home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’87 / Source ƒ.sit / Source ƒ / C ƒ / CITADEL BBS 'C' SRC / CTDL.C < prev    next >
C/C++ Source or Header  |  1987-01-14  |  30KB  |  1,156 lines

  1. /************************************************************************/
  2. /*                ctdl.c                    */
  3. /*        Command-interpreter code for Citadel            */
  4. /************************************************************************/
  5.  
  6. #include "ctdl.h"
  7.  
  8. /************************************************************************/
  9. /*                history                 */
  10. /*                                    */
  11. /* 86Aug16 HAW    Kill history for file because of space problems.    */
  12. /* 84May18 JLS/HAW Greeting modified for coherency.            */
  13. /* 84Apr04 HAW    Upgrade to BDS 1.50a begun.                */
  14. /* 83Mar08 CrT    Aide-special functions installed & tested...        */
  15. /* 83Feb24 CrT/SB Menus rearranged.                    */
  16. /* 82Dec06 CrT    2.00 release.                        */
  17. /* 82Nov05 CrT    removed main() from room2.c and split into sub-fn()s    */
  18. /************************************************************************/
  19.  
  20. /************************************************************************/
  21. /*                Contents                */
  22. /*                                    */
  23. /*    doAide()        handles Aide-only    commands    */
  24. /*    doChat()        handles C(hat)        command     */
  25. /*    doEnter()        handles E(nter)     command     */
  26. /*    doForget()        handles Z(Forget room)    command     */
  27. /*    doGoto()        handles G(oto)        command     */
  28. /*    doHelp()        handles H(elp)        command     */
  29. /*    doKnown()        handles K(nown rooms)    command     */
  30. /*    doLogin()        handles L(ogin)     command     */
  31. /*    doLogout()        handles T(erminate)    command     */
  32. /*    doRead()        handles R(ead)        command     */
  33. /*    doRegular()        fanout for above commands        */
  34. /*    doSkip()        handles S(kip)        command     */
  35. /*    doSysop()        handles sysop-only    commands    */
  36. /*    doUngoto()        handles U(ngoto)    command     */
  37. /*    getCommand()        prints prompt and gets command char    */
  38. /*    greeting()        System-entry blurb etc            */
  39. /*    main()            has the central menu code        */
  40. /************************************************************************/
  41.  
  42. /************************************************************************/
  43. /*        External declarations in CTDL.C             */
  44. /************************************************************************/
  45. char   ExitToMsdos = FALSE;    /* True when time to bring system down    */
  46. int    exitValue = CRASH_EXIT;
  47.  
  48. char    *confirm = "confirm";
  49. char    *NoDownloads = "\n Sorry, this room does not allow downloads\n";
  50.  
  51. /************************************************************************/
  52. /*        External variable definitions for CTDL.C        */
  53. /************************************************************************/
  54. extern struct config cfg;    /* The main variable to be saved    */
  55. extern struct aRoom    roomBuf;    /* Room buffer            */
  56. extern struct msgB    msgBuf;     /* Message buffer        */
  57. extern struct msgB    tempMess;    /* Message buffer        */
  58. extern struct logBuffer logBuf;     /* Person's log buffer        */
  59. extern struct rTable    roomTab[];    /* Room index for RAM        */
  60. extern struct lTable    *logTab;    /* Log    index for RAM        */
  61. extern long        FDSectCount;    /* size of files in directory    */
  62. extern int        thisRoom;    /* Current room         */
  63. extern long int     pulledMLoc;    /* Loc of msg to be pulled    */
  64. extern ulong        pulledMId;    /* Id of msg to be pulled    */
  65. extern char        noBanner;
  66. extern FILE        *bannerFile;
  67. extern char        *who_str;
  68. extern char        remoteSysop;
  69. extern char        onConsole;    /* Where IO is ...        */
  70. extern char        whichIO;    /* Where IO is ...        */
  71. extern char        outFlag;
  72. extern char        expert;     /* User expert?         */
  73. extern char        aide;        /* User aide?            */
  74. extern char        loggedIn;    /* Are we logged in?        */
  75. extern char        echo;
  76. extern char        newCarrier;    /* Just got carrier, hurrah!    */
  77. extern char        justLostCarrier;/* Boo, hiss!            */
  78. extern char        usingWCprotocol;/* WC protocol flag        */
  79. extern char        textDownload;    /* flag             */
  80. extern char        haveCarrier;
  81. extern char        *baseRoom;
  82. extern int        lastRoom;    /* For Ungoto command        */
  83. extern char        heldMess;
  84. extern char        anyEcho;
  85.  
  86. extern int    acount;
  87. #define AUDIT    9000
  88. extern char    audit[AUDIT];
  89.  
  90. /************************************************************************/
  91. /*        External function definitions for CTDL.C        */
  92. /************************************************************************/
  93. char toUpper();
  94. char iChar();
  95. long getNumber();
  96.  
  97. /************************************************************************/
  98. /*    doAide() handles the aide-only menu                */
  99. /*        return FALSE to fall invisibly into default error msg    */
  100. /************************************************************************/
  101. char doAide(moreYet, first)
  102. char moreYet;
  103. char first;    /* first parameter if TRUE        */
  104. {
  105.     label oldName;
  106.     int  rm, roomExist();
  107.     char chatStack;
  108.  
  109.     if (!aide)     return FALSE;
  110.  
  111.     if (moreYet)   first = '\0';
  112.  
  113.     mPrintf("ide special fn: ");
  114.  
  115.     if (first)       oChar(first);
  116.  
  117.     switch (toUpper(   first ? first : iChar()      )) {
  118.     case 'C':
  119.     chatStack = cfg.noChat;
  120.     cfg.noChat = FALSE;
  121.     mPrintf("hat\n ");
  122.     if (whichIO == MODEM)        ringSysop();
  123.     else                interact() ;
  124.     cfg.noChat = chatStack;
  125.     break;
  126.     case 'D':
  127.     sPrintf(msgBuf.mbtext, "The following empty rooms deleted by %s: ",
  128.                         logBuf.lbname);
  129.     mPrintf("elete empty rooms\n ");
  130.     if (!getYesNo(confirm))
  131.        break;
  132.     strCpy(oldName, roomBuf.rbname);
  133.     indexRooms();
  134.  
  135.     if ((rm=roomExist(oldName)) != ERROR)    getRoom(rm);
  136.     else                    getRoom(LOBBY);
  137.  
  138.     aideMessage( /* noteDeletedMessage== */ FALSE );
  139.     break;
  140.     case 'E':
  141.     mPrintf("dit room\n  \n");
  142.     renameRoom();
  143.     break;
  144.     case 'I':
  145.     mPrintf("nsert message\n ");
  146.     if (
  147.         thisRoom   == AIDEROOM
  148.         ||
  149.         pulledMId  == 0l
  150.     )   {
  151.         mPrintf("nope!");
  152.         break;
  153.     }
  154.     if (!getYesNo(confirm))
  155.         break;
  156.     note2Message(pulledMId, pulledMLoc);
  157.     putRoom(thisRoom);
  158.     noteRoom();
  159.     sPrintf(
  160.         msgBuf.mbtext,
  161.         "Following message inserted in %s> by %s",
  162.         roomBuf.rbname,
  163.         logBuf.lbname
  164.     );
  165.     aideMessage( /* noteDeletedMessage == */ TRUE);
  166.     break;
  167.     case 'K':
  168.     mPrintf("ill room\n ");
  169.     if (
  170.         thisRoom == LOBBY
  171.         ||
  172.         thisRoom == MAILROOM
  173.         ||
  174.         thisRoom == AIDEROOM
  175.     ) {
  176.         mPrintf(" not here!");
  177.         break;
  178.     }
  179.     if (!getYesNo(confirm))   break;
  180.  
  181.     sPrintf(
  182.         msgBuf.mbtext,
  183.         "%s> killed by %s",
  184.         roomBuf.rbname,
  185.         logBuf.lbname
  186.     );
  187.     aideMessage( /* noteDeletedMessage == */ FALSE);
  188.  
  189.     roomBuf.rbflags.INUSE = FALSE;
  190.     putRoom(thisRoom);
  191.     noteRoom();
  192.     getRoom(LOBBY);
  193.     break;
  194.     case 'S':
  195.     mPrintf("et Date\n ");
  196.     changeDate();
  197.     break;
  198.     case '?':
  199.     tutorial("aide.mnu");
  200.     break;
  201.     default:
  202.     if (!expert)    mPrintf(" ?(Type '?' for menu)\n "    );
  203.     else        mPrintf(" ?\n "             );
  204.     break;
  205.     }
  206.     return TRUE;
  207. }
  208.  
  209. /************************************************************************/
  210. /*    doChat()                            */
  211. /************************************************************************/
  212. doChat(moreYet, first)
  213. char moreYet;    /* TRUE to accept following parameters    */
  214. char first;    /* first parameter if TRUE        */
  215. {
  216.     if (moreYet)   first = '\0';
  217.  
  218.     if (first)       oChar(first);
  219.  
  220.     mPrintf("hat ");
  221.  
  222.     if (whichIO != MODEM) {
  223.     interact() ;
  224.     return ;
  225.     }
  226.  
  227.     if (cfg.noChat)   {
  228.     tutorial("nochat.blb");
  229.     return;
  230.     }
  231.  
  232.     ringSysop();
  233. }
  234.  
  235. /************************************************************************/
  236. /*    doEnter() handles E(nter) command                */
  237. /************************************************************************/
  238. doEnter(moreYet, first)
  239. char moreYet;    /* TRUE to accept following parameters    */
  240. char first;    /* first parameter if TRUE        */
  241. {
  242. #define CONFIGURATION    0
  243. #define MESSAGE     1
  244. #define PASSWORD    2
  245. #define ROOM        3
  246. #define ENTERFILE    4
  247. #define CONTINUED    5
  248. #define NETWORK     6
  249.  
  250. #define NOPE        0
  251. #define GIVEMENU    1
  252. #define NOMENU        2
  253.     char what;            /* one of above seven */
  254.     char abort, done, WC;
  255.     char letter;
  256.  
  257.     if (moreYet)   first = '\0';
  258.  
  259.     abort    = NOPE     ;
  260.     done    = FALSE  ;
  261.     WC        = FALSE  ;
  262.     what    = MESSAGE;
  263.  
  264.     mPrintf("nter ");
  265.  
  266.     if (thisRoom != MAILROOM && !loggedIn && !cfg.unlogEnterOk) {
  267.     mPrintf("Must log in to enter messages except MAIL to the SYSOP\n ");
  268.     return FALSE;
  269.     }
  270.  
  271.     if (first)       oChar(first);
  272.  
  273.     do    {
  274.     outFlag = OUTOK;
  275.  
  276.     letter = (toUpper(   first ? first : iChar()   ));
  277.     switch (letter) {
  278.     case '\r':
  279.     case '\n':
  280.         moreYet    = FALSE;
  281.         break;
  282.     case 'X':
  283.     case 'W':
  284.         mPrintf("%s protocol ", (letter == 'W') ? "C" : "modem");
  285.         WC = TRUE;
  286.         break;
  287.     case 'F':
  288.         if (roomBuf.rbflags.MSDOSDIR == 1) {
  289.         mPrintf("ile upload ");
  290.         if ((abort = ((!loggedIn) ? NOMENU : NOPE)) == NOMENU)
  291.             mPrintf("\n Must be logged in!\n ");
  292.         else if ((abort = ((!roomBuf.rbflags.UPLOAD)
  293.                          ? NOMENU : NOPE)) == NOMENU)
  294.          mPrintf("\n Sorry, this room is not available for upload.\n ");
  295.         what    = ENTERFILE;
  296.         done    = TRUE;
  297.         break;
  298.         }
  299.     default:
  300.         abort = GIVEMENU;
  301.         break;
  302.     case 'C':
  303.         if (WC)
  304.         abort = GIVEMENU;
  305.         else {
  306.         mPrintf("onfiguration ");
  307.         what        = CONFIGURATION;
  308.         done        = TRUE;
  309.         }
  310.         break;
  311.     case 'M':
  312.         mPrintf("essage "       );
  313.         what    = MESSAGE;
  314.         done    = TRUE;
  315.         break;
  316.     case 'P':
  317.         if (WC)
  318.         abort = GIVEMENU;
  319.         else {
  320.         mPrintf("assword "     );
  321.         what        = PASSWORD       ;
  322.         done        = TRUE;
  323.         }
  324.         break;
  325.     case 'R':
  326.         if (WC)
  327.         abort = GIVEMENU;
  328.         else {
  329.         mPrintf("oom "           );
  330.         if (!cfg.nonAideRoomOk && !aide)   {
  331.             mPrintf(" ?-- must be aide to create room\n ");
  332.             abort   = NOMENU;
  333.             break;
  334.         }
  335.         if (!loggedIn) {
  336.             mPrintf("!Must log in to create a new room\n");
  337.             abort = NOMENU;
  338.             break;
  339.         }
  340.         what        = ROOM;
  341.         done        = TRUE;
  342.         }
  343.         break;
  344.         case 'H':
  345.         if (WC)
  346.         abort = GIVEMENU;
  347.         else {
  348.         mPrintf("eld Message ");
  349.         what = CONTINUED;
  350.         done = TRUE;
  351.         }
  352.             break;
  353.     case 'N':
  354.         mPrintf("et-Message ");
  355.         what = NETWORK;
  356.             done = TRUE;
  357.             break;
  358.     }
  359.     first = '\0';
  360.     if (abort != NOPE) {
  361.         mPrintf("? ");
  362.         if (abort == GIVEMENU && (!expert || letter == '?'))
  363.         tutorial("entopt.mnu");
  364.     }
  365.     } while (!done && moreYet && abort == NOPE);
  366.  
  367.     doCR();
  368.  
  369.     if (abort == NOPE) {
  370.     if (whichIO != CONSOLE && thisRoom == MAILROOM) echo = CALLER;
  371.     switch (what) {
  372.     case CONFIGURATION  :    configure(loggedIn);       break;
  373.     case MESSAGE        :    makeMessage(WC)    ;       break;
  374.     case PASSWORD        :    newPW()        ;       break;
  375.     case ROOM        :    makeRoom()       ;       break;
  376.     case ENTERFILE        :    upLoad()       ;       break;
  377.     case CONTINUED        :    hldMessage()       ;       break;
  378.     case NETWORK        :    netMessage(WC)       ;       break;
  379.     }
  380.     echo = BOTH;
  381.     }
  382. }
  383.  
  384. /************************************************************************/
  385. /*    doForget() handles (Forget room) command            */
  386. /************************************************************************/
  387. doForget(expand, first)
  388. char expand, first;
  389. {
  390.     int i;
  391.  
  392.     if (!expand) {
  393.     mPrintf("\bForget %s \n ", roomBuf.rbname);
  394.     if (thisRoom == LOBBY     ||
  395.         thisRoom == MAILROOM ||
  396.         thisRoom == AIDEROOM) {
  397.         mPrintf("!Can't forget this room! \n ");
  398.         return ;
  399.     }
  400.     if (!getYesNo(confirm))   return;
  401.     i = (roomBuf.rbgen + FORGET_OFFSET) % MAXGEN;    /* Set up offset*/
  402.     logBuf.lbgen[thisRoom] = i << GENSHIFT;     /* Save it    */
  403.     gotoRoom(baseRoom, 'S');
  404.     }
  405.     else {
  406.     mPrintf("\b\b ");
  407.     listRooms(FGTRMS);
  408.     }
  409. }
  410.  
  411. /************************************************************************/
  412. /*    doGoto() handles G(oto) command                 */
  413. /************************************************************************/
  414. doGoto(expand, first)
  415. char expand;    /* TRUE to accept following parameters    */
  416. char first;    /* first parameter if TRUE        */
  417. {
  418.     label roomName;
  419.  
  420.     outFlag = IMPERVIOUS;
  421.     mPrintf("oto ");
  422.  
  423.     if (!expand) {
  424.     gotoRoom("", 'R');
  425.     return;
  426.     }
  427.  
  428.     getNormStr("", roomName, NAMESIZE, ECHO);
  429.  
  430.     if (roomName[0] == '?') {
  431.     listRooms(LINNEW);
  432.     listRooms(NOROLD);
  433.     }
  434.     else
  435.     gotoRoom(roomName, 'R');
  436. }
  437.  
  438. /************************************************************************/
  439. /*    doHelp() handles H(elp) command                 */
  440. /************************************************************************/
  441. doHelp(expand, first)
  442. char expand;    /* TRUE to accept following parameters    */
  443. char first;    /* first parameter if TRUE        */
  444. {
  445.     label fileName;
  446.  
  447.     mPrintf("elp ");
  448.     if (!expand) {
  449.     mPrintf("\n\n");
  450.     tutorial("dohelp.hlp");
  451.     return;
  452.     }
  453.  
  454.     getNormStr("", fileName, 9, ECHO);
  455.     if (strLen(fileName) == 0)
  456.     strCpy(fileName, "dohelp");
  457.     if (fileName[0] == '?')    tutorial("helpopt.hlp");
  458.     else {
  459.     /* adding the extention makes things look simpler for        */
  460.     /* the user... and restricts the files which can be read    */
  461.     strCat(fileName, ".hlp");
  462.     tutorial(fileName);
  463.     }
  464. }
  465.  
  466. /************************************************************************/
  467. /*    doKnown() handles K(nown rooms) command.            */
  468. /************************************************************************/
  469. doKnown(expand, first)
  470. char expand;    /* TRUE to accept following parameters    */
  471. char first;    /* first parameter if TRUE        */
  472. {
  473.     mPrintf("nown rooms ");
  474.     if (!expand) {
  475.     mPrintf("\n ");
  476.     listRooms(LINNEW);
  477.     listRooms(NOROLD);
  478.     }
  479.     else
  480.     searchRooms();
  481. }
  482.  
  483. /************************************************************************/
  484. /*    doLogin() handles L(ogin) command                */
  485. /************************************************************************/
  486. doLogin(moreYet, first)
  487. char moreYet;    /* TRUE to accept following parameters    */
  488. char first;    /* first parameter if TRUE        */
  489. {
  490.     label passWord;
  491.  
  492.     mPrintf("ogin ");
  493.     if (!moreYet)   mPrintf("\n");
  494.     if (loggedIn)   {
  495.     mPrintf("\n ?Already logged in!\n ");
  496.     return;
  497.     }
  498.     echo    = CALLER;
  499.     getNormStr(moreYet ? "" : " password (just carriage return if new)",
  500.                   passWord, NAMESIZE, (moreYet) ? ECHO : NO_ECHO);
  501.     echo    = BOTH;
  502.     login(passWord);
  503. }
  504.  
  505. /************************************************************************/
  506. /*    doLogout() handles T(erminate) command                */
  507. /************************************************************************/
  508. doLogout(expand, first)
  509. char expand;    /* TRUE to accept following parameters    */
  510. char first;    /* first parameter if TRUE        */
  511. {
  512.  
  513.     if (expand)   first = '\0';
  514.  
  515.     mPrintf("erminate ");
  516.  
  517.     if (heldMess)
  518.      mPrintf("\n WARNING: You have a message in your Hold Message Buffer!\n ");
  519.  
  520.     if (first)     oChar(first);
  521.  
  522.     switch (toUpper(    first ? first : iChar()    )) {
  523.     case '?':
  524.     mPrintf("\n Logout options:\n \n ");
  525.  
  526.     mPrintf("Quit-also\n "        );
  527.     mPrintf("Stay\n "        );
  528.     break;
  529.     case 'Q':
  530.     mPrintf("uit-also\n ");
  531.     if (!expand)   {
  532.        if (!getYesNo(confirm))   break;
  533.     }
  534.     if (!onLine()) break;
  535.     terminate( /* hangUp == */ TRUE);
  536.     break;
  537.     case 'S':
  538.     mPrintf("tay\n ");
  539.     terminate( /* hangUp == */ FALSE);
  540.     break;
  541.     }
  542. }
  543.  
  544. /************************************************************************/
  545. /*    doRead() handles R(ead) command                 */
  546. /************************************************************************/
  547. doRead(moreYet, first)
  548. char moreYet;    /* TRUE to accept following parameters    */
  549. char first;    /* first parameter if TRUE        */
  550. {
  551.     int  fDir(), transmitFile(), tutorial();
  552.     long sectors, bytes;
  553.     char abort, doDir, done, hostFile, whichMess, revOrder, status, WC;
  554.     char letter;
  555.     char formatted;
  556.     label fileName;
  557.  
  558.  
  559.     if (moreYet)   first = '\0';
  560.  
  561.     mPrintf("\bread ");
  562.  
  563.     abort    = FALSE;
  564.     doDir    = FALSE;
  565.     hostFile    = FALSE;
  566.     revOrder    = FALSE;
  567.     status    = FALSE;
  568.     WC        = WC_NONE;
  569.     formatted    = FALSE;
  570.     whichMess    = NEWoNLY;
  571.  
  572.     if (thisRoom == MAILROOM && !loggedIn  &&  !cfg.unlogReadOk)   {
  573.     showMessages(whichMess, revOrder);
  574.     return;
  575.     }
  576.  
  577.     if (!loggedIn  &&  !cfg.unlogReadOk)   {
  578.     mPrintf("Must log in to read\n ");
  579.     return;
  580.     }
  581.  
  582.     if (first)       oChar(first);
  583.  
  584.     do {
  585.     outFlag = OUTOK;
  586.     done = TRUE;
  587.  
  588.     letter = toUpper(first ? first : iChar());
  589.     switch (letter) {
  590.     case '\n':
  591.     case '\r':
  592.         moreYet    = FALSE;
  593.         break;
  594.     case 'A':
  595.         if (hostFile) break;
  596.         mPrintf("ll");
  597.         whichMess    = OLDaNDnEW;
  598.         break;
  599.     case 'F':
  600.         if (!hostFile) {
  601.         mPrintf("orward");
  602.         revOrder    = FALSE;
  603.         whichMess   = OLDaNDnEW;
  604.         }
  605.         else {
  606.         mPrintf("ormatted");
  607.         formatted = TRUE;
  608.         }
  609.         break;
  610.     case 'G':
  611.         if (hostFile) break;
  612.         mPrintf("lobal new-messages");
  613.         whichMess    = GLOBALnEW;
  614.         break;
  615.     case 'N':
  616.         if (hostFile) break;
  617.         mPrintf("ew ");
  618.         whichMess    = NEWoNLY;
  619.         break;
  620.     case 'O':
  621.         if (hostFile) break;
  622.         mPrintf("ld Reverse");
  623.         revOrder    = TRUE;
  624.         whichMess    = OLDoNLY;
  625.         break;
  626.     case 'R':
  627.         if (hostFile) break;
  628.         mPrintf("everse");
  629.         revOrder    = TRUE;
  630.         whichMess    = OLDaNDnEW;
  631.         break;
  632.     case 'S':
  633.         if (hostFile) break;
  634.         mPrintf("tatus\n ");
  635.         status    = TRUE;
  636.         break;
  637.     case 'X':
  638.     case 'W':
  639.         if (hostFile) break;
  640.         mPrintf("%s protocol ", (letter == 'W') ? "C" : "modem");
  641.         WC        = (letter == 'W') ? WC_NETWORK : WC_NORMAL;
  642.         done    = FALSE;
  643.         break;
  644.     case 'B':
  645.         if (hostFile) break;
  646.         if (roomBuf.rbflags.MSDOSDIR == 1 && loggedIn)   {
  647.         mPrintf("inary file(s) ");
  648.         if (roomBuf.rbflags.DOWNLOAD == 1 || TheSysop() ||
  649.                               remoteSysop) {
  650.             hostFile        = TRUE ;
  651.             textDownload    = FALSE;
  652.             break;
  653.         }
  654.         else {
  655.             mPrintf(NoDownloads);
  656.             abort = TRUE;
  657.             break;
  658.         }
  659.         }
  660.     case 'D':
  661.         if (hostFile) break;
  662.         if (roomBuf.rbflags.MSDOSDIR == 1)     {
  663.         mPrintf("irectory ");
  664.         if (roomBuf.rbflags.DOWNLOAD || TheSysop() || remoteSysop) {
  665.             doDir   = TRUE;
  666.             break;
  667.         }
  668.         else {
  669.             mPrintf(NoDownloads);
  670.             abort = TRUE;
  671.             break;
  672.         }
  673.         }
  674.     case 'T':
  675.         if (hostFile) break;
  676.         if (roomBuf.rbflags.MSDOSDIR == 1 && loggedIn)   {
  677.         mPrintf("extfile(s) ");
  678.         if (roomBuf.rbflags.DOWNLOAD || TheSysop() || remoteSysop) {
  679.             hostFile        = TRUE;
  680.             textDownload    = TRUE;
  681.             if (WC == WC_NONE) done   = FALSE;
  682.             break;
  683.         }
  684.         else {
  685.             mPrintf(NoDownloads);
  686.             abort = TRUE;
  687.             break;
  688.         }
  689.         }
  690.     default:
  691.         mPrintf("? ");
  692.         abort    = TRUE;
  693.         setUp(FALSE);
  694.         if (expert)   break;
  695.     case '?':
  696.         tutorial("readopt.mnu");
  697.         abort    = TRUE;
  698.         break;
  699.     }
  700.     first = '\0';
  701.     } while (!done && moreYet && !abort);
  702.  
  703.     if (abort) return;
  704.  
  705.     if (status) {
  706.     systat();
  707.     return;
  708.     }
  709.  
  710.     if (doDir) {
  711.     FDSectCount    = 0;      /* global fDir() totals sectors in   */
  712.     getNormStr("", fileName, NAMESIZE, ECHO);
  713.  
  714.     if (strLen(fileName))    wildCard(fDir, fileName);
  715.     else            wildCard(fDir, "*.*"   );
  716.  
  717.     mPrintf("\n Approximately %ld sectors total\n ", FDSectCount);
  718.     diskSpaceLeft(roomBuf.rbdisk + 'A', §ors, &bytes);
  719.     printf("\nThere are %ld bytes left on drive %c:\n", bytes,
  720.                           roomBuf.rbdisk + 'A');
  721.     return;
  722.     }
  723.  
  724.     if (hostFile) {
  725.     getNormStr("afn", fileName, NAMESIZE, ECHO);
  726.     usingWCprotocol = WC;
  727.     wildCard((formatted) ? tutorial : transmitFile, fileName);
  728.     usingWCprotocol = WC_NONE;
  729.     return;
  730.     }
  731.  
  732.     doCR();
  733. #ifdef OLD_STYLE
  734.     if (WC != WC_NONE) {
  735.     download(whichMess, revOrder, WC);
  736.     return;
  737.     }
  738.  
  739.     if (whichMess != GLOBALnEW)   {
  740.     showMessages(whichMess, revOrder);
  741.     } else {
  742.     while (outFlag != OUTSKIP   &&     gotoRoom("", 'R'))   {
  743.         givePrompt();
  744.         mPrintf("read new\n ");
  745.         showMessages(NEWoNLY, revOrder);
  746.     }
  747.     }
  748. #else
  749.     if (WC != WC_NONE) {
  750.     download(whichMess, revOrder, WC);
  751.     return;
  752.     }
  753.  
  754.     if (whichMess != GLOBALnEW)   {
  755.     showMessages(whichMess, revOrder);
  756.     } else {
  757.     doGlobal(revOrder);
  758.     }
  759. #endif
  760. }
  761.  
  762. #define MAX_USER_ERRORS 25
  763. /************************************************************************/
  764. /*    doRegular()                            */
  765. /************************************************************************/
  766. char doRegular(x, c)
  767. char x, c;
  768. {
  769.     static int errorCount = 0;
  770.     char       toReturn, *strchr();
  771.  
  772.     toReturn = FALSE;
  773.  
  774.     if (strchr("CEFGHKLNORSTU?", toUpper(c)) != NULL) errorCount = 0;
  775.     else                          errorCount++;
  776.  
  777.     switch (c) {
  778.  
  779.     case 'C': doChat(  x, '\0');            break;
  780.     case 'E': doEnter( x, 'm' );            break;
  781.     case 'F': doRead(  x, 'f' );            break;
  782.     case 'G': doGoto(  x, '\0');            break;
  783.     case 'H': doHelp(  x, '\0');            break;
  784.     case 'K': doKnown( x, '\0');            break;
  785.     case 'L': doLogin( x, '\0');            break;
  786.     case 'N': doRead(  x, 'n' );            break;
  787.     case 'O': doRead(  x, 'o' );            break;
  788.     case 'R': doRead(  x, 'r' );            break;
  789.     case 'S': doSkip(  x, '\0');            break;
  790.     case 'T': doLogout(x, 'q' );            break;
  791.     case 'U': doUngoto(x, '\0');            break;
  792.  
  793.     case 0:
  794.     if (newCarrier)   {
  795.         greeting();
  796.         newCarrier    = FALSE;
  797.     }
  798.     if (justLostCarrier) {
  799.         justLostCarrier = FALSE;
  800.         if (loggedIn) terminate(FALSE);
  801.     }
  802.     break;    /* irrelevant value */
  803.     case '?':
  804.     tutorial("mainopt.mnu");
  805.     if (whichIO == CONSOLE)   mPrintf("\n^l: SysOp privileged fns\n ");
  806.     break;
  807.  
  808.     case 'A': if (!doAide(x, 'E'))  toReturn=TRUE;    break;
  809.     case 'Z': doForget(x, '\0');              break;
  810.     default:
  811.     if (errorCount > MAX_USER_ERRORS) {
  812.         logMessage(EVIL_SIGNAL, "", 'E');
  813.         interpret(cfg.pHangUp);
  814.     }
  815.     toReturn=TRUE;
  816.     break;
  817.     }
  818.     return  toReturn;
  819. }
  820.  
  821. /************************************************************************/
  822. /*    doSkip() handles the <S>kip a room command            */
  823. /************************************************************************/
  824. doSkip(expand, first)
  825. char first, expand;
  826. {
  827.     label roomName;             /* In case of ".Skip" */
  828.  
  829.     outFlag = IMPERVIOUS;
  830.     mPrintf("kip %s> goto ", roomTab[thisRoom].rtname);
  831.     if (expand)
  832.     getNormStr("", roomName, NAMESIZE, ECHO);
  833.     else
  834.     roomName[0] = '\0';
  835.     if (roomName[0] == '?')
  836.     tutorial("skip.hlp");
  837.     else {
  838.     roomTab[thisRoom].rtflags.SKIP = 1;    /* Set bit */
  839.     gotoRoom(roomName, 'S');
  840.     }
  841. }
  842.  
  843. /************************************************************************/
  844. /*    doSysop() handles the sysop-only menu                */
  845. /*        return FALSE to fall invisibly into default error msg    */
  846. /************************************************************************/
  847. char doSysop(c, first)
  848. char c;
  849. char first;    /* first parameter if TRUE        */
  850. {
  851.     ulong        temp;
  852.     char        systemPW[200];
  853.     extern char     *VERSION;
  854.     extern char     *netVersion;
  855.     extern int        fixVers, majorVers;
  856.     label        who;
  857.     struct logBuffer    lBuf;
  858.     int         logNo, ltabSlot;
  859.  
  860.     if (!onConsole) {
  861.     if (!aide || strLen(cfg.sysPassword) == 0)
  862.         return TRUE;
  863.     echo        = CALLER;
  864.     getNormStr("password", systemPW, 199, NO_ECHO);
  865.     echo        = BOTH;
  866.     if (strCmp(systemPW, cfg.sysPassword) != 0)
  867.         return TRUE;
  868.     remoteSysop = TRUE;
  869.     }
  870.  
  871.     while (onLine()) {
  872.  
  873.     outFlag = OUTOK;
  874.     mPrintf("\n privileged fn: ");
  875.  
  876.     switch (toUpper(   first ? first : iChar()    )) {
  877.     case 'Z':
  878.         mPeek(); break;
  879.     case 'B':
  880.         interpret(cfg.pBauds[(int) getNumber(" baud (0-3)", 0l, 3l)]);
  881.         break;
  882.     case 'E':
  883.         mPrintf("cho %sabled\n ", (anyEcho = !anyEcho) ? "en" : "dis");
  884.         break;
  885.     case 'F':
  886.         mPrintf("ile grab\n ");
  887.         ingestFile();
  888.         break;
  889.     case 'A':
  890.         mPrintf("bort\n ");
  891.         return FALSE;
  892.     case 'C':
  893.         mPrintf("hat mode %sabled\n ",
  894.         (cfg.noChat = !cfg.noChat)
  895.         ?
  896.         "dis"
  897.         :
  898.         "en"
  899.         );
  900.         break;
  901.     case 'D':
  902.         cfg.debug = !cfg.debug;
  903.         mPrintf("ebug switch=%d\n \n", cfg.debug);
  904.         break;
  905.     case 'I':
  906.         mPrintf("nformation\n ");
  907.         mPrintf("Citadel-86 V%s\n Net version %s", VERSION, netVersion);
  908.         mPrintf("\n Commands version %d.%d\n ", majorVers, fixVers);
  909.         mPrintf("ctdlcnfg.sys version %d\n ", cfg.paramVers);
  910.         break;
  911.     case 'K':
  912.         mPrintf("ill account\n ");
  913.         getNormStr(who_str, who, NAMESIZE, ECHO);
  914.         logNo   = findPerson(who, &lBuf);
  915.         if (logNo == ERROR)   {
  916.         mPrintf("No such person\n ");
  917.         break;
  918.         }
  919.         if (lBuf.credit != 0)
  920.         mPrintf("%s has %d credit for l-d!", who);
  921.         if (!getYesNo(confirm))   break;
  922.         mPrintf("%s deleted\n ", who);
  923.         ltabSlot = PWSlot(lBuf.lbpw, /* load == */ FALSE);
  924.         lBuf.lbname[0] = '\0';
  925.         lBuf.lbpw[0  ] = '\0';
  926.         lBuf.lbflags.L_INUSE = FALSE;
  927.  
  928.         putLog(&lBuf, logNo);
  929.  
  930.         logTab[ltabSlot].ltpwhash        = 0;
  931.         logTab[ltabSlot].ltnmhash        = 0;
  932.  
  933.         break;
  934.     case 'M':
  935.         mPrintf("\bSystem now on MODEM\n ");
  936.     /*  if (!remoteSysop) { */
  937.         if (whichIO != MODEM) {
  938.         whichIO = MODEM;
  939.         setUp(FALSE);
  940.         }
  941.         mPrintf("Chat mode %sabled\n ", cfg.noChat    ?  "dis"  :  "en");
  942.         if (cfg.debug)     mPrintf("Debug mode on\n "  );
  943. #ifdef NEED_VISIBLE
  944.         if (visibleMode) mPrintf("Visible mode on\n ");
  945. #endif
  946.         return FALSE;
  947.     case 'O':
  948.         mPrintf("ther Commands\n ");
  949.         systemCommands();
  950.         break;
  951.     case 'P':
  952.         mPrintf("\baide privilege set/clear\n ");
  953.         getNormStr(who_str, who, NAMESIZE, ECHO);
  954.         logNo   = findPerson(who, &lBuf);
  955.         if (logNo == ERROR)   {
  956.         mPrintf("No such person\n ");
  957.         break;
  958.         }
  959.  
  960.         if (lBuf.lbflags.AIDE == 1)
  961.         lBuf.lbflags.AIDE = 0;
  962.         else
  963.         lBuf.lbflags.AIDE = 1;
  964.         mPrintf(
  965.         "%s %s aide privileges\n ",
  966.         who,
  967.         (lBuf.lbflags.AIDE == 1)  ?  "gets"  :    "loses"
  968.         );
  969.         if (!getYesNo(confirm))   break;
  970.  
  971.         putLog(&lBuf, logNo);
  972.  
  973.         /* see if it is us: */
  974.         if (loggedIn  &&  strCmpU(logBuf.lbname, who)==SAMESTRING)     {
  975.         aide = (lBuf.lbflags.AIDE == 1) ? TRUE : FALSE;
  976.         logBuf.lbflags.AIDE = (aide)    ? TRUE : FALSE;
  977.         }
  978.         break;
  979.     case 'S':
  980.         changeDate();
  981.         break;
  982. #ifdef NEED_VISIBLE
  983.     case 'V':
  984.         mPrintf(" VisibleMode==%d\n ",  visibleMode = !visibleMode);
  985.         break;
  986. #endif
  987.     case 'X':
  988.         mPrintf("\bexit to MS-DOS\n \n");
  989.         if (!getYesNo(confirm))   break;
  990.         ExitToMsdos = TRUE;
  991.         exitValue    = (remoteSysop) ? REMOTE_SYSOP_EXIT : SYSOP_EXIT;
  992.         return FALSE;
  993.     case 'N':
  994.         netStuff();
  995.         break;
  996.     case 'R':
  997.         mPrintf("einitialize Modem\n ");
  998.         modemInit();
  999.         break;
  1000.     case 'Q':
  1001.         temp = getNumber(" Set oldest to", 0l, 200000l);
  1002.         if (temp != 0l) cfg.oldest = temp;
  1003.         break;
  1004.     case '?':
  1005.         tutorial("ctdlopt.mnu");
  1006.         break;
  1007.     default:
  1008.         if (!expert)    mPrintf(" ?(Type '?' for menu)\n "        );
  1009.         else        mPrintf(" ?\n "                );
  1010.         break;
  1011.     }
  1012.     }
  1013. }
  1014.  
  1015. /************************************************************************/
  1016. /*    doUngoto() handles the Ungoto command                */
  1017. /************************************************************************/
  1018. doUngoto(moreYet, first)
  1019. char moreYet;
  1020. char first;    /* first parameter if TRUE        */
  1021. {
  1022.     label target;
  1023.  
  1024.     mPrintf("ngoto ");
  1025.     if (!moreYet) {
  1026.     doCR();
  1027.     strCpy(target, "");
  1028.     }
  1029.     else {
  1030.     getNormStr("", target, NAMESIZE, ECHO);
  1031.     }
  1032.     retRoom(target);
  1033. }
  1034.  
  1035. /************************************************************************/
  1036. /*    getCommand() prints menu prompt and gets command char        */
  1037. /*    Returns: char via parameter and expand flag as value  --    */
  1038. /*         i.e., TRUE if parameters follow else FALSE.        */
  1039. /************************************************************************/
  1040. char getCommand(c)
  1041. char *c;
  1042. {
  1043.     char BBSCharReady();
  1044.     char expand;
  1045.  
  1046.     outFlag = OUTOK;
  1047.  
  1048.     givePrompt();
  1049.  
  1050.     *c = toUpper(iChar());
  1051.  
  1052.     expand  = (
  1053.     *c == ' '
  1054.     ||
  1055.     *c == '.'
  1056.     ||
  1057.     *c == ','
  1058.     ||
  1059.     *c == '/'
  1060.     );
  1061.     if (expand) *c = toUpper(iChar());
  1062.  
  1063.     if (justLostCarrier) {
  1064.     justLostCarrier = FALSE;
  1065.     if (loggedIn) terminate(FALSE);
  1066.     }
  1067.     return expand;
  1068. }
  1069.  
  1070. /************************************************************************/
  1071. /*    greeting() gives system-entry blurb etc             */
  1072. /************************************************************************/
  1073. greeting()
  1074. {
  1075.     extern char *VERSION;
  1076.  
  1077.     if (loggedIn) terminate(FALSE);
  1078.  
  1079.     setUp(TRUE);     pause(10);
  1080.  
  1081.     setmem(audit, AUDIT, ' ');
  1082.     acount = 0;
  1083.  
  1084.     doCR();
  1085.     if (noBanner)
  1086.     mPrintf("Welcome to %s\n", cfg.codeBuf + cfg.nodeTitle);
  1087.     else
  1088.     writeTutorial(bannerFile, FALSE);
  1089.     mPrintf(" Running: Citadel-86 (V%s) \n \n", VERSION);
  1090.     printDate();
  1091.     mPrintf("\n H for Help\n ");
  1092.  
  1093.     printf("Chat mode %sabled\n", cfg.noChat ? "dis" : "en");
  1094.     printf("\n 'MODEM' mode.\n "               );
  1095.     printf("(<ESC> for CONSOLE mode.)\n "           );
  1096.     while (MIReady())
  1097.     inp();
  1098.  
  1099.     gotoRoom(baseRoom, 'R');
  1100.     lastRoom = -1;
  1101. }
  1102.  
  1103. /************************************************************************/
  1104. /*    main() contains the central menu code                */
  1105. /************************************************************************/
  1106. main(argc, argv)
  1107. int  argc;
  1108. char **argv;
  1109. {
  1110.     extern char logNetResults, IBMinterrupts;
  1111.     char c, x;
  1112.     char errMsg;
  1113.     char getCommand();
  1114.     
  1115.     cfg.weAre        = CITADEL;
  1116.     errMsg = FALSE;
  1117.     while (argc >= 2) {
  1118.     argc--;
  1119.     if (strCmpU(argv[argc], "+netlog") == SAMESTRING)
  1120.         logNetResults = TRUE;
  1121.     else
  1122.     if (strCmpU(argv[argc], "+interrupts") == SAMESTRING) {
  1123.         IBMinterrupts = TRUE;
  1124.         printf("Interrupts on\n");
  1125.     }
  1126.     else
  1127.         errMsg = TRUE;
  1128.     }
  1129.     initCitadel();
  1130.     greeting();
  1131.  
  1132.     if (errMsg) {
  1133.     sPrintf(msgBuf.mbtext,
  1134.  "System brought up from apparent crash. See header for time it came up.");
  1135.     aideMessage(FALSE);
  1136.     }
  1137.  
  1138.     logMessage(FIRST_IN, "", FALSE);
  1139.  
  1140.     while (!ExitToMsdos)  {
  1141.     x    = getCommand(&c);
  1142.  
  1143.     outFlag = OUTOK;
  1144.  
  1145.     if ((c==CNTRLl)  ?  doSysop(0, '\0')  :  doRegular(x, c))  {
  1146.         if (!expert)    mPrintf(" ? (Type '?' for menu)\n \n"   );
  1147.         else        mPrintf(" ?\n \n"                );
  1148.     }
  1149.     }
  1150.     if (loggedIn) terminate( /* hangUp == */ TRUE);
  1151.     logMessage(LAST_OUT, "", FALSE);
  1152.     writeSysTab(); 
  1153.     modemClose();
  1154.     exit(exitValue);
  1155. }
  1156.